<?php

namespace App\Http\Validate\Invoice;

use App\Http\Validate\AbstractBaseValidate;
use App\Models\Invoice\InvoiceHeadModel;
use App\Models\Invoice\InvoiceHistoryBusinessRelModel;
use App\Models\Invoice\InvoiceHistoryModel;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\MessageBag;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class InvoiceValidate extends AbstractBaseValidate
{
    function getRules(): array
    {
        // TODO: Implement getRules() method.
        return [];
    }

    function getAttributes(): array
    {
        // TODO: Implement getAttributes() method.
        return [];
    }

    function registerValidateRules(): void
    {
        // TODO: Implement registerValidateRules() method.
        Validator::extend('mobile', function ($attribute, $value, $parameters, $validator) {
            return $validator->validateRegex(
                $attribute,
                $value,
                ['/^1\d{10}$/'],
                "手机号格式非法"
            );
        });
    }

    function getMessages(): array
    {
        // TODO: Implement getMessages() method.
        return [];
    }

    /**
     * 开票业务参数校验
     *
     * @param array $params
     * @return MessageBag|object
     * @throws ValidationException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function applyInvoiceValidate(array $params)
    {
        $isCompanySpecial = (($params["headerType"] ?? "") == InvoiceHistoryModel::HEADER_TYPE_1 && ($params["invoiceType"] ?? "") == InvoiceHistoryModel::INVOICE_TYPE_1);

        return self::getInstance()->validate(
            [
                "invoiceHeaderId",
                "businessType",
                "headerType",
                "invoiceType",
                "mobile",
                "email",
                "invoiceTotalAmount",
                "invoiceTitle",
                "companyTaxNumber",
                "companyRegisterAddress",
                "companyRegisterMobile",
                "companyDepositBank",
                "companyDepositBankNum",
                "businessRel"
            ],
            $params,
            [
                "invoiceHeaderId"                  => [
                    "required",
                    "int",
                    Rule::exists((new InvoiceHeadModel())->getTable(), "id")
                ],
                "businessType"                     => self::intInValidateBuild(true,
                    InvoiceHistoryModel::BUSINESS_TYPE_TEXT),
                "headerType"                       => self::intInValidateBuild(true,
                    InvoiceHistoryModel::HEADER_TYPE_TEXT),
                "invoiceType"                      => self::intInValidateBuild(true,
                    InvoiceHistoryModel::INVOICE_TYPE_TEXT),
                "mobile"                           => "sometimes|mobile",
                "email"                            => "sometimes|email",
                "invoiceTotalAmount"               => "required|string",
                "invoiceTitle"                     => "required|string|max:36",
                "companyTaxNumber"                 => "exclude_unless:headerType," . InvoiceHistoryModel::HEADER_TYPE_1 . "|required|string|max:36",
                "companyRegisterAddress"           => Rule::when($isCompanySpecial, "required|string|max:72", ""),
                "companyRegisterMobile"            => Rule::when($isCompanySpecial, "required|string|max:36", ""),
                "companyDepositBank"               => Rule::when($isCompanySpecial, "required|string|max:72", ""),
                "companyDepositBankNum"            => Rule::when($isCompanySpecial, "required|string|max:36", ""),
                "businessRel"                      => [
                    "required",
                    "array",
                    "min:1",
                    function ($attribute, $value, $fail) {
                        $businessIds = array_column($value, "businessId");
                        if (empty($businessIds)) {
                            $fail("业务订单号数据缺失");
                        }
                        $invoiceHistoryBusinessRel = InvoiceHistoryBusinessRelModel::query()
                                                                                   ->whereIn("businessId", $businessIds)
                                                                                   ->get();
                        if ($invoiceHistoryBusinessRel->isNotEmpty()) {
                            $exists = InvoiceHistoryModel::query()
                                                         ->whereIn("id",
                                                             $invoiceHistoryBusinessRel->pluck("invoiceHistoryId")
                                                                                       ->toArray())
                                                         ->whereIn("status", [
                                                             InvoiceHistoryModel::STATUS_1,
                                                             InvoiceHistoryModel::STATUS_3,
                                                             InvoiceHistoryModel::STATUS_4
                                                         ])
                                                         ->get();
                            if ($exists->isNotEmpty()) {
                                $fail("存在已开票的业务订单,请核实后再发起操作");
                            }
                        }
                    }
                ],
                "businessRel.*.businessId"         => "required|string|max:120",
                "businessRel.*.businessOrderTime"  => "required|date_format:Y-m-d H:i:s",
                "businessRel.*.invoiceTotalAmount" => "required|string",
            ]
        );
    }

    /**
     * @param array $params
     * @return MessageBag|object
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     */
    public static function reApplyInvoiceValidate(array $params)
    {
        $isCompanySpecial = $params["headerType"] ?? "" == InvoiceHistoryModel::HEADER_TYPE_1 && $params["invoiceType"] ?? "" == InvoiceHistoryModel::INVOICE_TYPE_1;
        return self::getInstance()->validate(
            [
                "id",
                "businessType",
                "headerType",
                "invoiceType",
                "mobile",
                "email",
                "invoiceTitle",
                "companyTaxNumber",
                "companyRegisterAddress",
                "companyRegisterMobile",
                "companyDepositBank",
                "companyDepositBankNum",
            ],
            $params,
            [
                "id"                     => [
                    "required",
                    "int",
                    Rule::exists((new InvoiceHistoryModel())->getTable(), "id")
                        ->where("status", InvoiceHistoryModel::STATUS_3)
                        ->where(function ($query) {
                            $query->where("createdAt", ">=", time() - 93 * 60 * 60 * 24);

                        })
                        ->where("isDeleted", 0),
                    function ($attribute, $value, $fail) {
                        $exists = InvoiceHistoryModel::query()->where("newInvoiceId", $value)->first();
                        if ($exists) {
                            $fail("换开记录已存在，暂不支持二次换开");
                        }
                    }
                ],
                "businessType"           => self::intInValidateBuild(true,
                    InvoiceHistoryModel::BUSINESS_TYPE_TEXT),
                "headerType"             => self::intInValidateBuild(true,
                    InvoiceHistoryModel::HEADER_TYPE_TEXT),
                "invoiceType"            => self::intInValidateBuild(true,
                    InvoiceHistoryModel::INVOICE_TYPE_TEXT),
                "mobile"                 => "sometimes|mobile",
                "email"                  => "sometimes|email",
                "invoiceTitle"           => "required|string|max:36",
                "companyTaxNumber"       => "exclude_unless:headerType," . InvoiceHistoryModel::HEADER_TYPE_1 . "|required|string|max:36",
                "companyRegisterAddress" => Rule::when($isCompanySpecial, "required|string|max:72", ""),
                "companyRegisterMobile"  => Rule::when($isCompanySpecial, "required|string|max:36", ""),
                "companyDepositBank"     => Rule::when($isCompanySpecial, "required|string|max:72", ""),
                "companyDepositBankNum"  => Rule::when($isCompanySpecial, "required|string|max:36", ""),
            ]
        );
    }

    /**
     * 回调校验
     *
     * @param array $params
     * @return MessageBag|object
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     */
    public static function notifyValidate(array $params)
    {
        return self::getInstance()->validate(
            ["orderId", "data"],
            $params,
            [
                "orderId"       => [
                    "required",
                    "string",
                    function ($attribute, $value, $fail) {
                        $actuallyVal = str_replace("hc-", "", $value);
                        $exists      = InvoiceHistoryModel::query()->where("orderId", $actuallyVal)->first();
                        if (!$exists) {
                            $fail("{$value} 数据查询异常");
                        }

                        if (!in_array($exists->status,
                            [InvoiceHistoryModel::STATUS_1, InvoiceHistoryModel::STATUS_4])) {
                            $fail("{$actuallyVal} 订单回调状态异常");
                        }
                    }
                ],
                "data"          => "required|array",
                "data.*.fpData" => "required|string",
                "data.*.pdf"    => "required|string",
            ]
        );
    }

    /**
     * 回调校验
     *
     * @param array $params
     * @return MessageBag|object
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     */
    public static function redInvoiceValidate(array $params)
    {
        return self::getInstance()->validate(
            ["invoiceId"],
            $params,
            [
                "invoiceId" => [
                    "required",
                    "int",
                    Rule::exists((new InvoiceHistoryModel())->getTable(), "id")
                        ->where("status", InvoiceHistoryModel::STATUS_3)
                ],
            ]
        );
    }

    /**
     * 列表校验
     *
     * @param array $params
     * @return MessageBag|object
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     */
    public static function listValidate(array $params)
    {
        return self::getInstance()->validate(
            ["pageSize", "pageNum", "businessType"],
            $params,
            [
                "pageSize"     => "required|int|min:1|max:100",
                "pageNum"      => "required|int|min:1",
                "businessType" => "sometimes"
            ]
        );
    }
}
